package com.matt.service.impl;

import com.google.common.collect.ImmutableMap;
import com.matt.domain.TeachingTemplete;
import com.matt.domain.TeachingTempleteArea;
import com.matt.domain.TeachingTempleteCourseVo;
import com.matt.domain.TeachingTempleteDetail;
import com.matt.foundation.constant.TeachingTempleteConstant;
import com.matt.commons.exception.BusinessException;

import com.matt.foundation.model.ErrorCode;
import com.matt.foundation.utils.ModelUtil;
import com.matt.repository.*;
import com.matt.service.TeachingTempleteService;
import org.apache.commons.lang.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Describle This Class Is
 * @Author ZengMin
 * @Date 2018/12/19 15:20
 * @Company Matt
 */
@Service
public class TeachTempleteServiceImpl implements TeachingTempleteService {

    @Autowired
    TeachingTempleteRepository teachingTempleteRepository;

    @Autowired
    TeachingTempleteDetailRepository teachingTempleteDetailRepository;

    @Autowired
    TeachingTempleteAreaRepository teachingTempleteAreaRepository;


    @Override
    @Transactional
    public TeachingTemplete saveTemplete(TeachingTemplete teachingTemplete, Integer type) {
        //保存模板主表
        TeachingTemplete templete = teachingTempleteRepository.saveAndFlush(teachingTemplete);
        List<TeachingTempleteDetail> saves = Lists.newArrayList();
        List<TeachingTempleteDetail> teachingTempleteDetail = teachingTemplete.getTeachingTempleteDetail();
        int sort = 0;
        for (TeachingTempleteDetail d : teachingTempleteDetail) {
            if (d.getSort() == 0)
                d.setSort(sort++);
            d.setTempleteId(templete.getId());
            d.setCreateStaffName(templete.getCreateStaffName());
            d.setCreateStaffId(templete.getCreateStaffId());
            String id = d.getId();
            if (StringUtils.isBlank(d.getId())) {
                id = ModelUtil.getCleanUUID();
                d.setId(id);
            }
            //设置主类型中文
            d.setTypeVal(TeachingTempleteConstant.MODULE.getValue(d.getType()));

            //设置子类型中文
            switch (d.getType()) {
                case TeachingTempleteConstant.TEMPLETE_TYPE_PAD:
                    d.setChildTypeVal(TeachingTempleteConstant.PAD.getValue(d.getChildType()));
                    break;
                case TeachingTempleteConstant.TEMPLETE_TYPE_COURSE:
                    d.setChildTypeVal(TeachingTempleteConstant.COURSE.getValue(d.getChildType()));
                    break;
                case TeachingTempleteConstant.TEMPLETE_TYPE_COMMON_CHILD:
                    d.setChildTypeVal(TeachingTempleteConstant.COURSE_COMMON.getValue(d.getChildType()));
                    break;
                case TeachingTempleteConstant.TEMPLETE_TYPE_FLOW_CHILD:
                    d.setChildTypeVal(TeachingTempleteConstant.COURSE_FLOW.getValue(d.getChildType()));
                    break;
                default:
                    break;
            }
            //判断子类型
            List<TeachingTempleteDetail> teachingTempleteChild = d.getTeachingTempleteChild();
            //如果存在子类型
            if (!Objects.isNull(teachingTempleteChild) && teachingTempleteChild.size() > 0) {
                int detailSort = 0;
                for (TeachingTempleteDetail t : teachingTempleteChild) {
                    String cid = t.getId();
                    if (StringUtils.isBlank(cid)) cid = ModelUtil.getCleanUUID();
                    switch (t.getType()) {
                        case TeachingTempleteConstant.TEMPLETE_TYPE_COMMON_CHILD:
                            t.setChildTypeVal(TeachingTempleteConstant.COURSE_COMMON.getValue(t.getChildType()));
                            break;
                        case TeachingTempleteConstant.TEMPLETE_TYPE_FLOW_CHILD:
                            t.setChildTypeVal(TeachingTempleteConstant.COURSE_FLOW.getValue(t.getChildType()));
                            break;
                        default:
                            break;
                    }
                    t.setParentId(id);
                    t.setId(cid);
                    t.setCreateStaffId(templete.getCreateStaffId());
                    t.setCreateStaffName(templete.getCreateStaffName());
                    if (t.getSort() == 0) t.setSort(detailSort++);
                    saves.add(t);
                }
            }
            saves.add(d);
        }
        //新增
        if (type == TeachingTempleteConstant.TEACHING_ADD) {
            List<TeachingTempleteDetail> save = teachingTempleteDetailRepository.saveAll(saves);
            templete.setTeachingTempleteDetail(save);
        }
        //更新
        if (type == TeachingTempleteConstant.TEACHING_UPDATE) {
            List<TeachingTempleteDetail> save = Lists.newArrayList();
            saves.stream().forEach(o -> {
                TeachingTempleteDetail teachingTempleteDetail1 = teachingTempleteDetailRepository.saveAndFlush(o);
                save.add(teachingTempleteDetail1);
            });
            templete.setTeachingTempleteDetail(save);
        }
        return templete;
    }

    @Override
    public List<TeachingTemplete> getTempleteAll() {
        return teachingTempleteRepository.findAll();
    }

    @Override
    public TeachingTemplete getTempleteDetail(String templeteId) {
        TeachingTemplete one = teachingTempleteRepository.getOne(templeteId);
        if (Objects.isNull(one))
            throw new BusinessException(ErrorCode.MATERIAL_NOT_EXIST, "模板不存在！");
        //主类型
        List<TeachingTempleteDetail> templeteDetails = teachingTempleteDetailRepository.findByTempleteIdOrderByTypeAscSortAsc(templeteId);
        List<String> ids = templeteDetails.stream().map(TeachingTempleteDetail::getId).collect(Collectors.toList());
        List<TeachingTempleteDetail> finalChildList = Lists.newArrayList();
        //查询所有子类型
        List<TeachingTempleteDetail> child = teachingTempleteDetailRepository.findByParentIdInOrderByTypeAscSortAsc(ids);
        //处理字段类型
        for (TeachingTempleteDetail t : templeteDetails) {
            List<TeachingTempleteDetail> collect = child.stream().filter(o -> o.getParentId().equals(t.getId())).collect(Collectors.toList());
            List<TeachingTempleteCourseVo> teachingTempleteCourseVos = TeachingTempleteCourseVo.of(collect, t.getId(), t.getName());
            t.setTeachingTempleteCourseVos(teachingTempleteCourseVos);
            finalChildList.add(t);
        }
        //分主类型
        List<TeachingTempleteDetail> padList = Lists.newArrayList();
        List<TeachingTempleteDetail> courseList = Lists.newArrayList();
        finalChildList.stream().forEach(o -> {
            int type = o.getType();
            switch (type) {
                case TeachingTempleteConstant.TEMPLETE_TYPE_PAD:
                    padList.add(o);
                    break;
                case TeachingTempleteConstant.TEMPLETE_TYPE_COURSE:
                    courseList.add(o);
                    break;
                default:
                    break;
            }
        });
        one.setTempleteDetail(ImmutableMap.of("pad", padList, "course", courseList));
        return one;
    }

    @Override
    @Transactional
    public List<TeachingTempleteArea> bindArea(List<TeachingTempleteArea> teachingTempleteArea) {
        if (teachingTempleteArea.size() > 0) {
            TeachingTempleteArea templeteArea = teachingTempleteArea.get(0);
            teachingTempleteAreaRepository.deleteByTempleteId(templeteArea.getTempleteId());
            List<TeachingTempleteArea> save = teachingTempleteAreaRepository.saveAll(teachingTempleteArea);
            return save;
        }
        return null;
    }

    @Override
    public List<TeachingTempleteArea> getBindArea(String templeteId) {
        List<TeachingTempleteArea> teachingTempleteAreas = teachingTempleteAreaRepository.findByTempleteId(templeteId);
        return teachingTempleteAreas;
    }

    @Override
    @Transactional
    public boolean delTeachingTemplete(String templeteId) {
        TeachingTemplete one = teachingTempleteRepository.getOne(templeteId);
        if (Objects.isNull(one))
            throw new BusinessException(ErrorCode.MATERIAL_NOT_EXIST,"模板已删除或不存在！");

        //删主表
        teachingTempleteRepository.deleteById(templeteId);
        //删子表
        //取父级
        List<TeachingTempleteDetail> templeteDetails = teachingTempleteDetailRepository.findByTempleteIdOrderByTypeAscSortAsc(templeteId);
        List<String> collect = templeteDetails.stream().map(TeachingTempleteDetail::getId).collect(Collectors.toList());
        //取子级
        List<TeachingTempleteDetail> templeteDetailList = teachingTempleteDetailRepository.findByParentIdInOrderByTypeAscSortAsc(collect);
        teachingTempleteDetailRepository.deleteAll(templeteDetails);
        teachingTempleteDetailRepository.deleteAll(templeteDetailList);
        //删除模板对应园区数据
        teachingTempleteAreaRepository.deleteByTempleteId(templeteId);
        return true;
    }

    @Transactional
    @Override
    public boolean delTeachingDetail(String id) {
        try {
            teachingTempleteDetailRepository.deleteById(id);
        }catch (EmptyResultDataAccessException e){
            throw new BusinessException(ErrorCode.MATERIAL_NOT_EXIST,"删除失败，该子类型可能已被删除！");
        }
        return true;
    }

    @Override
    public List<TeachingTemplete> getTempleteByArea(String areaId) {
        List<TeachingTemplete> byAreaId = teachingTempleteRepository.findByAreaId(areaId);
        return byAreaId;
    }

    @Override
    public Object getTempleteByType(String templeteId, Integer type) {
        List<TeachingTempleteDetail> templeteDetailList = teachingTempleteDetailRepository.findByTempleteIdAndTypeOrderBySortAsc(templeteId, type);
        return templeteDetailList;
    }

}
